/*
 * @Author: quit
 * @Date: 2023-03-08 23:52:45
 * @LastEditTime: 2023-03-09 14:28:51
 * @Descripttion: 函数及其定义
 * @notice:
 */

/**
 * @description: 函数的定义的方式
 * 1. 函数声明
 * 2. 函数表达式
 * 一个函数有输入和输出,要在TS中对其进行约束,需要给函数的参数和返回值都设置一个类型
 *
 */
// function add(x, y) {
//     return x + y;
// }
// let _add = function (x, y) {
//     return x + y;
// };
// console.log(add(1, '2'), _add(true, 3));

function add(x: number, y: number): number {
    return x + y;
}
let _add = function (x: number, y: number): number {
    return x + y;
};
// console.log(add(1, '2'), _add(true, 3));
// console.log(add(1, 2), _add(1, 3));

// 自定义一个函数类型,这里的 => 并不是ES6中的箭头函数,这里的是TS种的函数定义
let add2: (x: number, y: number) => number;

interface MyFn {
    (x11: number, y11: number): number;
}
let add3: MyFn = add;
// 正常使用TS时会使用接口来定义函数的样子,避免我们在函数的定义时代码过于臃肿,简洁代码

/**
 * @description: 剩余参数
 * 把所有参数收集到一个变量里;可以使用 ... 拓展运算符,将传入参数序列转换为数组
 * ...变量名(参数名)
 */
function getBall(x: string, ...args: string[]): string {
    console.log(args);
    return x + '-' + args.join('-');
}
console.log(getBall('basketball', 'football', 'baseball'));

/**
 * @description: 函数重载
 * 同名函数的参数个数、类型、顺序必须其中一个不同
 * 重载允许一个函数接收不同数量或类型的参数时,做出不同的处理,为同一个函数提供多个函数定义来进行函数重载
 * 在定义重载的时候,一定要把最精确的定义放在最前面.因为查找重载列表,会从第一个重载定义开始匹配
 * 在函数实现时需要使用 联合类型 将所有可能的类型包含进去
 * 函数重载是为了通过传入不同类型的参数获得不同的结果,如果传入的参数不同得到的结果都一样那就不需要进行函数重载
 */

function add4(x: number, y: number): number;
function add4(x: string, y: string): string;
// 上面的为函数的重载;下面的为函数的实现
function add4(x: number | string, y: number | string): number | string {
    if (typeof x === 'number' && typeof y === 'number') {
        return x + y;
    } else if (typeof x === 'string' && typeof y === 'string') {
        return x + y;
    }
}

let v1 = add4(1, 2);
let v2 = add4('1', '2');

export {};
